
<!DOCTYPE html
  PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   
      <title>12.4.&nbsp; SOAP 网络服务查错</title>
      <link rel="stylesheet" href="../diveintopython.css" type="text/css">
      <link rev="made" href="mailto:f8dy@diveintopython.org">
      <meta name="generator" content="DocBook XSL Stylesheets V1.52.2">
      <meta name="keywords" content="Python, Dive Into Python, tutorial, object-oriented, programming, documentation, book, free">
      <meta name="description" content="Python from novice to pro">
      <link rel="home" href="../toc/index.html" title="Dive Into Python">
      <link rel="up" href="index.html" title="第&nbsp;12&nbsp;章&nbsp;SOAP Web 服务">
      <link rel="previous" href="first_steps.html" title="12.3.&nbsp;步入 SOAP">
      <link rel="next" href="wsdl.html" title="12.5.&nbsp;WSDL 介绍">
   </head>
   <body>
      <table id="Header" width="100%" border="0" cellpadding="0" cellspacing="0" summary="">
         <tr>
            <td id="breadcrumb" colspan="5" align="left" valign="top">导航：<a href="../index.html">起始页</a>&nbsp;&gt;&nbsp;<a href="../toc/index.html">Dive Into Python</a>&nbsp;&gt;&nbsp;<a href="index.html">SOAP Web 服务</a>&nbsp;&gt;&nbsp;<span class="thispage"> SOAP 网络服务查错</span></td>
            <td id="navigation" align="right" valign="top">&nbsp;&nbsp;&nbsp;<a href="first_steps.html" title="上一页: “步入 SOAP”">&lt;&lt;</a>&nbsp;&nbsp;&nbsp;<a href="wsdl.html" title="下一页: “WSDL 介绍”">&gt;&gt;</a></td>
         </tr>
         <tr>
            <td colspan="3" id="logocontainer">
               <h1 id="logo"><a href="../index.html" accesskey="1">深入 Python :Dive Into Python 中文版</a></h1>
               <p id="tagline">Python 从新手到专家 [Dip_5.4b_CPyUG_Release]</p>
            </td>
            <td colspan="3" align="right">
               <form id="search" method="GET" action="http://www.google.com/custom">
                  <p><label for="q" accesskey="4">Find:&nbsp;</label><input type="text" id="q" name="q" size="20" maxlength="255" value=""> <input type="submit" value="搜索"><input type="hidden" name="domains" value="woodpecker.org.cn/diveintopython"><input type="hidden" name="sitesearch" value="www.woodpecker.org.cn/diveintopython"></p>
               </form>
            </td>
         </tr>
      </table>
      <!--#include virtual="/inc/ads" -->
      <div class="section" lang="zh_cn">
         <div class="titlepage">
            <div>
               <div>
                  <h2 class="title"><a name="soap.debug"></a>12.4.&nbsp; <span class="acronym">SOAP</span> 网络服务查错
                  </h2>
               </div>
            </div>
            <div></div>
         </div>
         <div class="abstract">
            <p> <span class="acronym">SOAP</span> 提供了一个很方便的方法用以查看背后的情形。
            </p>
         </div>
         <p><tt class="classname">SOAPProxy</tt> 的两个小设置就可以打开查错模式。
         </p>
         <div class="example"><a name="d0e30604"></a><h3 class="title">例&nbsp;12.7.&nbsp; <span class="acronym">SOAP</span> 网络服务查错
            </h3><pre class="screen">
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput"><span class='pykeyword'>from</span> SOAPpy <span class='pykeyword'>import</span> SOAPProxy</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">url = <span class='pystring'>'http://services.xmethods.net:80/soap/servlet/rpcrouter'</span></span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">n = <span class='pystring'>'urn:xmethods-Temperature'</span></span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">server = SOAPProxy(url, namespace=n)</span>     <a name="soap.debug.1.1"></a><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12">
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">server.config.dumpSOAPOut = 1</span>            <a name="soap.debug.1.2"></a><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12">
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">server.config.dumpSOAPIn = 1</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">temperature = server.getTemp(<span class='pystring'>'27502'</span>)</span>    <a name="soap.debug.1.3"></a><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12">
<span class="computeroutput">*** Outgoing SOAP ******************************************************
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/1999/XMLSchema"&gt;
&lt;SOAP-ENV:Body&gt;
&lt;ns1:getTemp xmlns:ns1="urn:xmethods-Temperature" SOAP-ENC:root="1"&gt;
&lt;v1 xsi:type="xsd:string"&gt;27502&lt;/v1&gt;
&lt;/ns1:getTemp&gt;
&lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;
************************************************************************
*** Incoming SOAP ******************************************************
&lt;?xml version='1.0' encoding='UTF-8'?&gt;
&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
&lt;SOAP-ENV:Body&gt;
&lt;ns1:getTempResponse xmlns:ns1="urn:xmethods-Temperature"
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&gt;
&lt;return xsi:type="xsd:float"&gt;80.0&lt;/return&gt;
&lt;/ns1:getTempResponse&gt;

&lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;
************************************************************************
</span>
<tt class="prompt">&gt;&gt;&gt; </tt><span class="userinput">temperature</span>
<span class="computeroutput">80.0</span>
</pre><div class="calloutlist">
               <table border="0" summary="Callout list">
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#soap.debug.1.1"><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">首先，和平常一样，建立带有服务 <span class="acronym">URL</span> 和命名空间的 <tt class="classname">SOAPProxy</tt>。
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#soap.debug.1.2"><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">然后，通过设置 <tt class="varname">server.config.dumpSOAPIn</tt> 和 <tt class="varname">server.config.dumpSOAPOut</tt> 打开查错模式。
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#soap.debug.1.3"><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">最后，和平常一样，调用远程 <span class="acronym">SOAP</span> 方法。<span class="acronym">SOAP</span> 库将会输出送出的 XML 请求文档和收到的 XML 返回文档。这是 <tt class="classname">SOAPProxy</tt> 为你做的所有工作。有点恐怖，不是吗？让我们来分析一下。
                     </td>
                  </tr>
               </table>
            </div>
         </div>
         <p>大部分 XML 请求文档都基于模板文件。忽略所有命名空间声明这些对于所有 <span class="acronym">SOAP</span> 调用都一成不变的东西。这个 “<span class="quote">函数调用</span>” 的核心是<tt class="sgmltag-element">&lt;Body&gt;</tt> 当中的部分：
         </p>
         <div class="informalexample"><pre class="programlisting">
&lt;ns1:getTemp                                 <a name="soap.debug.2.1"></a><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12">
  xmlns:ns1=<span class='pystring'>"urn:xmethods-Temperature"</span>       <a name="soap.debug.2.2"></a><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12">
  SOAP-ENC:root=<span class='pystring'>"1"</span>&gt;
&lt;v1 xsi:type=<span class='pystring'>"xsd:string"</span>&gt;27502&lt;/v1&gt;         <a name="soap.debug.2.3"></a><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12">
&lt;/ns1:getTemp&gt;
</pre><div class="calloutlist">
               <table border="0" summary="Callout list">
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#soap.debug.2.1"><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">这个元素名 <tt class="function">getTemp</tt> 就是函数名。<tt class="classname">SOAPProxy</tt> 使用 <a href="../scripts_and_streams/handlers_by_node_type.html" title="10.5.&nbsp;根据节点类型创建不同的处理器"><tt class="function">getattr</tt> 作为分发器</a>。有别于使用方法名分别调用本地方法，这里使用方法名构造了一个 XML 请求文档。
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#soap.debug.2.2"><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">函数的 XML 元素被存储于一个特别的命名空间，这个命名空间就是你在建立 <tt class="classname">SOAPProxy</tt> 对象时所指定的那个命名空间。也不必为 <tt class="literal">SOAP-ENC:root</tt> 而苦恼，因为它也是基于模板文件的。
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#soap.debug.2.3"><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">函数的参数也被记入 XML 文档。<tt class="classname">SOAPProxy</tt> 查看并确定每个参数的数据类型 (这里是 string 字符串类型)。参数的数据类型记入 <tt class="literal">xsi:type</tt> 属性，并在其后记入实际的字符串值。
                     </td>
                  </tr>
               </table>
            </div>
         </div>
         <p>返回的 XML 文档同样容易理解，重点在于知道应该忽略掉哪些内容。把注意力集中在 <tt class="sgmltag-element">&lt;Body&gt;</tt> 部分：
         </p>
         <div class="informalexample"><pre class="programlisting">
&lt;ns1:getTempResponse                             <a name="soap.debug.3.1"></a><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12">
  xmlns:ns1=<span class='pystring'>"urn:xmethods-Temperature"</span>           <a name="soap.debug.3.2"></a><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12">
  SOAP-ENV:encodingStyle=<span class='pystring'>"http://schemas.xmlsoap.org/soap/encoding/"</span>&gt;
&lt;<span class='pykeyword'>return</span> xsi:type=<span class='pystring'>"xsd:float"</span>&gt;80.0&lt;/<span class='pykeyword'>return</span>&gt;       <a name="soap.debug.3.3"></a><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12">
&lt;/ns1:getTempResponse&gt;
</pre><div class="calloutlist">
               <table border="0" summary="Callout list">
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#soap.debug.3.1"><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">服务器传回的值记录在 <tt class="sgmltag-element">&lt;getTempResponse&gt;</tt> 部分的几行中。通常包括函数名和回应 <tt class="literal"> (Response)</tt>。当然其他的内容也可能出现在这里，但 <tt class="classname">SOAPProxy</tt> 所重视的不是这里的元素名，而是命名空间。
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#soap.debug.3.2"><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">服务器返回时所使用的命名空间就是在请求时所用的命名空间，也就是在创建 <tt class="classname">SOAPProxy</tt> 对象时所指定的命名空间。本章稍后的部分中，我们将看到在创建 <tt class="classname">SOAPProxy</tt> 对象时忘记指定功能名空间会怎样。
                     </td>
                  </tr>
                  <tr>
                     <td width="12" valign="top" align="left"><a href="#soap.debug.3.3"><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12"></a> 
                     </td>
                     <td valign="top" align="left">这是返回值和它的数据类型 (浮点类型 float)。<tt class="classname">SOAPProxy</tt> 使用显式数据类型创建一个本地数据类型的 <span class="application">Python</span> 对象并返回之。
                     </td>
                  </tr>
               </table>
            </div>
         </div>
      </div>
      <table class="Footer" width="100%" border="0" cellpadding="0" cellspacing="0" summary="">
         <tr>
            <td width="35%" align="left"><br><a class="NavigationArrow" href="first_steps.html">&lt;&lt;&nbsp;步入 SOAP</a></td>
            <td width="30%" align="center"><br>&nbsp;<span class="divider">|</span>&nbsp;<a href="index.html#soap.divein" title="12.1.&nbsp;概览">1</a> <span class="divider">|</span> <a href="install.html" title="12.2.&nbsp;安装 SOAP 库">2</a> <span class="divider">|</span> <a href="first_steps.html" title="12.3.&nbsp;步入 SOAP">3</a> <span class="divider">|</span> <span class="thispage">4</span> <span class="divider">|</span> <a href="wsdl.html" title="12.5.&nbsp;WSDL 介绍">5</a> <span class="divider">|</span> <a href="introspection.html" title="12.6.&nbsp;以 WSDL 进行 SOAP 内省">6</a> <span class="divider">|</span> <a href="google.html" title="12.7.&nbsp;搜索 Google">7</a> <span class="divider">|</span> <a href="troubleshooting.html" title="12.8.&nbsp; SOAP 网络服务故障排除">8</a> <span class="divider">|</span> <a href="summary.html" title="12.9.&nbsp;小结">9</a>&nbsp;<span class="divider">|</span>&nbsp;
            </td>
            <td width="35%" align="right"><br><a class="NavigationArrow" href="wsdl.html">WSDL 介绍&nbsp;&gt;&gt;</a></td>
         </tr>
         <tr>
            <td colspan="3"><br></td>
         </tr>
      </table>
      <div class="Footer">
         <p class="copyright">Copyright © 2000, 2001, 2002, 2003, 2004 <a href="mailto:mark@diveintopython.org">Mark Pilgrim</a></p>
         <p class="copyright">Copyright © 2001, 2002, 2003, 2004, 2005, 2006, 2007 <a href="mailto:python-cn@googlegroups.com">CPyUG (邮件列表)</a></p>
      </div>
   </body>
</html>